package com.stone.framework.basic.dict.service.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.stone.framework.basic.dict.entity.DictCategory;
import com.stone.framework.basic.dict.entity.DictMember;
import com.stone.framework.basic.dict.repository.DictCategoryRepository;
import com.stone.framework.basic.dict.repository.DictMemberRepository;
import com.stone.framework.basic.dict.service.DictCategoryService;
import com.stone.framework.core.cache.BasicConstant;
import com.stone.framework.core.exception.BusinessException;
import com.stone.framework.core.util.Beans;
import com.stone.framework.message.basic.dict.DictCategoryPageReqBody;
import com.stone.framework.message.basic.dict.DictCategoryPageResBody;
import com.stone.framework.message.basic.dict.DictCategoryReqBody;

@Service
@Transactional(readOnly = true)
public class DictCategoryServiceImpl implements DictCategoryService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DictCategoryServiceImpl.class);

    @Autowired
    private DictCategoryRepository dictCategoryRepository;

    @Autowired
    private DictMemberRepository dictMemberRepository;

    @Override
    public Page<DictCategoryPageResBody> queryPage(DictCategoryPageReqBody reqBody, Pageable pageable) {
        DictCategory condition = new DictCategory();
        Beans.copyProperties(reqBody, condition);
        return dictCategoryRepository.findAll(condition, pageable).map(entity -> {
            DictCategoryPageResBody resBody = new DictCategoryPageResBody();
            Beans.copyProperties(entity, resBody);
            return resBody;
        });
    }

    @Override
    @Transactional(readOnly = false)
    public void save(DictCategoryReqBody reqBody) {
        int count = dictCategoryRepository.findByCode(reqBody.getCode()).size();
        if (count > 0) {
            throw new BusinessException("字典已存在，请重新输入");
        }
        DictCategory entity = new DictCategory();
        Beans.copyProperties(reqBody, entity);
        dictCategoryRepository.save(entity);
    }

    @Override
    @Transactional(readOnly = false)
    @CacheEvict(value = {BasicConstant.PREFIX_DICT, BasicConstant.PREFIX_DICT_KV}, key = "#reqBody.code")
    public void modify(DictCategoryReqBody reqBody) {
        DictCategory entity =
            dictCategoryRepository.findById(reqBody.getId()).orElseThrow(() -> new BusinessException("字典不存在"));

        Beans.copyProperties(reqBody, entity);
        List<DictCategory> list = dictCategoryRepository.findByCode(reqBody.getCode());

        if (list.size() > 1) {
            throw new BusinessException("字典代码重复，请重新输入");
        }
        dictCategoryRepository.save(list.get(0));
    }

    @Override
    @Transactional(readOnly = false)
    @CacheEvict(value = {BasicConstant.PREFIX_DICT, BasicConstant.PREFIX_DICT_KV}, key = "#reqBody.code")
    public void delete(DictCategoryReqBody reqBody) {
        DictCategory category =
            dictCategoryRepository.findById(reqBody.getId()).orElseThrow(() -> new BusinessException("字典不存在"));
        List<DictMember> list = dictMemberRepository.findByDictCategoryCode(category.getCode());

        dictMemberRepository.deleteInBatch(list);
        dictCategoryRepository.delete(category);
    }

    @Override
    @CacheEvict(value = {BasicConstant.PREFIX_DICT, BasicConstant.PREFIX_DICT_KV}, allEntries = true)
    public void refreshCache() {
        LOGGER.info("数据字典 [{}] [{}] 已刷新", BasicConstant.PREFIX_DICT, BasicConstant.PREFIX_DICT_KV);
    }

    @Override
    @CacheEvict(value = {BasicConstant.PREFIX_DICT, BasicConstant.PREFIX_DICT_KV}, key = "code")
    public void refreshCache(String code) {
        List<DictCategory> list = dictCategoryRepository.findByCode(code);
        if (list.isEmpty()) {
            throw new BusinessException("数据字典不存在");
        }
        LOGGER.info("数据字典 [{}] [{}] 已刷新", BasicConstant.PREFIX_DICT + ":::" + code,
            BasicConstant.PREFIX_DICT_KV + ":::" + code);
    }

}
